home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Snippets / Up⁄Down Arrows / ArrowTweak#2.c < prev    next >
Encoding:
Text File  |  1994-03-05  |  12.3 KB  |  471 lines  |  [TEXT/KAHL]

  1. //• UpDownArrowTester.c
  2.  
  3. //• By Eddy J. Gurney
  4.  
  5. //• Please send any improvements or bugs in the "heart" of this code
  6. //• (the part that actually does the up/down arrow thing) to
  7. //• <egurney@vcd.hp.com>.  I don't care about bugs in the "shell" 
  8. //• portion; it's just a quick hack used to test the up/down arrow thing!
  9.  
  10. //• If you find this code useful, a "thanks" in the About box of your
  11. //• app or an e-mail message would always be appreciated. :-)
  12.  
  13. #include <Palettes.h>
  14.  
  15. #define NIL                    0L
  16.  
  17. typedef enum DialogMode 
  18. {
  19.     Default,         //• "Control" keys only.
  20.     AllowAlpha,
  21.     AllowPrint,
  22.     AllowDigit,
  23.     AllowHexDigit,
  24.     AllowAlphaNum    
  25. } DialogMode;
  26.  
  27. //• ASCII codes */
  28. #define enterKey            0x03
  29. #define returnKey            0x0d
  30. #define escapeKey            0x1b
  31.  
  32. DialogMode    gDialogMode;
  33. Boolean        gOkActive;
  34.  
  35. void ToolBoxInit()
  36. {
  37.     InitGraf(&thePort);
  38.     InitFonts();
  39.     FlushEvents(everyEvent, 0);
  40.     InitWindows();
  41.     InitMenus();
  42.     TEInit();
  43.     InitDialogs(NIL);
  44.     MaxApplZone();
  45.     InitCursor();
  46.     
  47.     SetDAFont(applFont);
  48. }
  49.  
  50. void FrameDialogItem(DialogPtr theDialog, short theItem, Pattern thePattern)
  51. {
  52.     GrafPtr            savePort;
  53.     short            iType;
  54.     Handle            iHandle;
  55.     Rect            iRect;
  56.     PenState        savePen;
  57.     RGBColor        color;
  58.     PixPatHandle    pp;
  59.  
  60.     GetPort(&savePort);
  61.     SetPort(theDialog);
  62.     GetPenState(&savePen);
  63.  
  64.     if (thePattern == gray) 
  65.     {
  66.         color.red = 0x8000;
  67.         color.green = 0x8000;
  68.         color.blue = 0x8000;
  69.     } else if (thePattern == black) 
  70.     {
  71.         color.red = 0x0;
  72.         color.green = 0x0;
  73.         color.blue = 0x0;
  74.     }    
  75.     pp = NewPixPat();
  76.     MakeRGBPat(pp, &color);
  77.     PenPixPat(pp);
  78.     
  79.     GetDItem(theDialog, theItem, &iType, &iHandle, &iRect);
  80.     InsetRect(&iRect, -4, -4);
  81.     PenSize(3, 3);
  82. //•    PenPat(thePattern);
  83.     FrameRoundRect(&iRect, 16, 16);
  84.  
  85.     DisposPixPat(pp);
  86.     SetPenState(&savePen);
  87.     SetPort(savePort);
  88. }
  89.  
  90. void DoDialogUpdate(DialogPtr theDialog)
  91. {
  92.     GrafPtr    savePort;
  93.     
  94.     GetPort(&savePort);
  95.     SetPort(theDialog);
  96.     
  97.     BeginUpdate(theDialog);
  98.     UpdtDialog(theDialog, theDialog->visRgn);
  99.     FrameDialogItem(theDialog, ok, (gOkActive ? black : gray));
  100.     EndUpdate(theDialog);
  101.     SetPort(savePort);
  102. }
  103.  
  104. void DoDialogActivate(DialogPtr theDialog, Boolean active)
  105. {
  106.     SetPort(theDialog);
  107. }
  108.  
  109. pascal Boolean DialogFilter(DialogPtr theDialog, EventRecord *theEvent, short *theItem)
  110. {
  111.     short            iType;
  112.     Handle            iHandle;
  113.     Rect            iRect;
  114.     char            theChar;
  115.     long            endTicks;
  116.     Boolean            result = FALSE;
  117.     WindowPtr        theWindow;
  118.  
  119.     Point            mousePoint;
  120.     Rect            upArrowRect, downArrowRect, plainArrowRect;
  121.     Boolean            hiLit = FALSE;
  122.     Str255            theString;
  123.     long            theValue, theDelay;
  124.     PicHandle        upArrowPict, downArrowPict, plainArrowPict;
  125.  
  126.     theWindow = (WindowPtr)(theEvent->message);
  127.     switch (theEvent->what) 
  128.     {
  129.         case updateEvt:                    //• In case we're updating
  130.             if (theWindow == theDialog) //• the dialog...
  131.             {
  132.                 DoDialogUpdate(theDialog);    //• update it (duh).
  133.                 result = TRUE;                //• True!  We're updating.
  134.                 *theItem = 0;                //• But not because of an item.
  135.             } 
  136.             else 
  137.                 {
  138.                 //• Call main DoUpdate(w) routine here to prevent holes 
  139.                 //• in  background windows (see TN 304).
  140.             }
  141.         break;
  142.         
  143.         case activateEvt:                //• In case our dialog is being
  144.             if (theWindow == theDialog) //• activated (brought to front)...
  145.             {
  146.                 //• activate it (duh).
  147.                 DoDialogActivate(theDialog, (theEvent->modifiers & activeFlag) != 0);
  148.                 *theItem = 0;    //• But not because of an item.  More
  149.             }                     //• likely, because it was not active and
  150.             else                 //• was clicked in.
  151.                 {
  152.                 //• Call main DoActivate(w) routine here to deactivate old
  153.                 //• frontmost window to unhighlight scroll bars, etc.
  154.             }
  155.         break;
  156.         
  157.         case mouseDown:
  158.             //• Get handles to all possible arrows.
  159.             plainArrowPict = GetPicture(130);     //• Both arrows, no hit.
  160.             upArrowPict = GetPicture(131);        //• Both, top arrow hit.
  161.             downArrowPict = GetPicture(132);    //• Both, bottom hit.
  162.             
  163.             //• Where the event (mouseDown) was, is the mousePoint (duh).
  164.             mousePoint = theEvent->where;
  165.             //• Find out where that mouseDown was.
  166.             GlobalToLocal(&mousePoint);        
  167.             
  168.             //• Narrow that down to dialog item #5.
  169.             GetDItem(theDialog, 5, &iType, &iHandle, &iRect);
  170.             
  171.             //• The un-hit arrow rectangle is iRect.
  172.             plainArrowRect = iRect;
  173.             upArrowRect = iRect;        //• upArrowRect is iRect, too.
  174.             upArrowRect.bottom -= 15;    //• The bottom is 15 pixels up.
  175.             downArrowRect = iRect;        //• dawnArrow is iRect, too.
  176.             downArrowRect.top += 15;        //• The top is 15 pixels down.
  177.             
  178.             //• Calculate time til first auto-count.
  179.             endTicks = TickCount() + 15;    //• 15 tick delay.
  180.             
  181.             //• Get dialog item 4 - the TextEdit rectangle.
  182.             GetDItem(theDialog, 4, &iType, &iHandle, &iRect);
  183.             
  184.             //• Lock its handle.
  185.             HLock(iHandle);
  186.             
  187.             //• Get the text, via the handle, of the string.
  188.             GetIText(iHandle, theString);
  189.             
  190.             //• Make it into a numerical value.
  191.             StringToNum(theString, &theValue);    //• Convert to number.
  192.             
  193.             //• If the point in the (iRect) rect of the click was in
  194.             //• the up arrow...
  195.             if (PtInRect(mousePoint, &upArrowRect)) 
  196.             {    
  197.                 //• Draw the upArrowPict in the plainArrowRect.
  198.                 DrawPicture(upArrowPict, &plainArrowRect);
  199.                 
  200.                 //• Set initial delay for auto-increment.
  201.                 theDelay = 15;        
  202.                 hiLit = TRUE;    //• Yes, it's hilited.
  203.                 theValue++;        //• Increase the value by...
  204.                 
  205.                 //• converting the value as a string...
  206.                 NumToString(theValue, theString);
  207.                 
  208.                 //• and displaying that string.
  209.                 SetIText(iHandle, theString);
  210.                 
  211.                 //• Keep an eye on the above operations and continue
  212.                 //• while the user still holds the mouse button down.
  213.                 while (StillDown()) 
  214.                 {    
  215.                     //• Keep watching where the mouse point is.
  216.                     GetMouse(&mousePoint);
  217.                     
  218.                     //• If it's in the upArrowRect...
  219.                     if (PtInRect(mousePoint, &upArrowRect)) 
  220.                     {
  221.                         if (hiLit == FALSE) //• and it ain't hilited...
  222.                         {
  223.                             hiLit = TRUE;    //• hilite it, by...
  224.                             
  225.                             //• drawing the uparrow pict in plainArrowRect.
  226.                             DrawPicture(upArrowPict, &plainArrowRect);
  227.                         }
  228.                     } 
  229.                     else     //• Otherwise (other than mouse being in
  230.                         {    //• upArrowRect while still down)...
  231.                             if (hiLit == TRUE)     //• if it's hilited...
  232.                             {
  233.                                 theDelay = 15;    //• wait 15 ticks and...
  234.                                 hiLit = FALSE;    //• unhilite it, by...
  235.                                 
  236.                                 //• drawing the plainArrowPict there.
  237.                                 DrawPicture(plainArrowPict, &plainArrowRect);
  238.                             }
  239.                     }
  240.                     //• If enough time has passed, auto-increment value.
  241.                     //• If we're hilited and the 15 ticks are up...
  242.                     if (hiLit == TRUE && TickCount() >= endTicks) 
  243.                     {
  244.                         //• Increase the value in the TextEdit field.
  245.                         theValue++;        
  246.                         NumToString(theValue, theString);    //• Convert to string.
  247.                         SetIText(iHandle, theString);    //• Display it.
  248.                         SelIText(theDialog, 4, 0, 32767);    //• Select the whole thing.
  249.                         endTicks = TickCount() + theDelay;    //• Calc new delay time.
  250.                         if (theDelay)
  251.                             theDelay--;        //• Shorten delay time until it's zero.
  252.                     }
  253.                 } //• end "while StillDown()".
  254.             } //• end "click in up arrow".
  255.             
  256.             if (PtInRect(mousePoint, &downArrowRect)) 
  257.             {    //• Was click in down arrow?.
  258.                 DrawPicture(downArrowPict, &plainArrowRect);
  259.                 theDelay = 15;
  260.                 hiLit = TRUE;
  261.                 theValue--;        //• Decrement it.
  262.                 NumToString(theValue, theString);    //• Convert to string.
  263.                 SetIText(iHandle, theString);        //• Display it.
  264.                 
  265.                 while (StillDown()) 
  266.                 {    //• Track control if user still holding button.
  267.                     GetMouse(&mousePoint);
  268.                     if (PtInRect(mousePoint, &downArrowRect)) 
  269.                     {        //• In down arrow?.
  270.                         if (hiLit == FALSE) 
  271.                         {    //• If so and not highlighted, do it.
  272.                             hiLit = TRUE;
  273.                             DrawPicture(downArrowPict, &plainArrowRect);
  274.                         }
  275.                     } 
  276.                     else 
  277.                         {    //• Out of down arrow now, unhighlight and reset delay.
  278.                             if (hiLit == TRUE) 
  279.                             {
  280.                                 theDelay = 15;
  281.                                 hiLit = FALSE;
  282.                                 DrawPicture(plainArrowPict, &plainArrowRect);
  283.                             }
  284.                     }
  285.                     //• If enough time has passed, auto-decrement value.
  286.                     if (hiLit == TRUE && TickCount() >= endTicks) 
  287.                     {
  288.                         theValue--;        //• Increment value.
  289.                         NumToString(theValue, theString);    //• Convert to string.
  290.                         SetIText(iHandle, theString);    //• Display it.
  291.                         SelIText(theDialog, 4, 0, 32767);    //• Select the whole thing.
  292.                         endTicks = TickCount() + theDelay;    //• Calc new delay time.
  293.                         if (theDelay)
  294.                             theDelay--;        //• Shorten delay time until it's zero.
  295.                     }
  296.                 } //• end "while StillDown()".
  297.             } //• end "click in down arrow".
  298.             
  299.             HUnlock(iHandle);
  300.             SelIText(theDialog, 4, 0, 32767);  //• Select the whole thing.
  301.  
  302.             if (hiLit == TRUE) 
  303.             {    //• Unhighlight arrow if necessary.
  304.                 DrawPicture(plainArrowPict, &plainArrowRect);
  305.                 *theItem = 5;
  306.                 result = TRUE;
  307.             }
  308.             
  309.             ReleaseResource((Handle)plainArrowPict);    //• Release arrow PICTs.
  310.             ReleaseResource((Handle)upArrowPict);
  311.             ReleaseResource((Handle)downArrowPict);
  312.         break;
  313.         
  314.         case mouseUp:
  315.         break;
  316.         
  317.         case keyDown:
  318.         case autoKey:
  319.             theChar = theEvent->message & charCodeMask;
  320.             if (theChar == returnKey || theChar == enterKey) 
  321.             {    //• Return/Enter key?.
  322.                 if (gOkActive) 
  323.                 {      //• Might be able to use contrlHilite field instead?.
  324.                     GetDItem(theDialog, ok, &iType, &iHandle, &iRect);
  325.                     HiliteControl((ControlHandle)iHandle, 1);
  326.                     Delay(8, &endTicks);
  327.                     HiliteControl((ControlHandle)iHandle, 0);
  328.                     *theItem = ok;
  329.                     return TRUE;
  330.                 } 
  331.                 else 
  332.                     {
  333.                         *theItem = 0;
  334.                         return TRUE;
  335.                 }
  336.             } 
  337.             else 
  338.                 if ((theChar == '.' && theEvent->modifiers & cmdKey) 
  339.                         || theChar == escapeKey) 
  340.                 {        //• ESC or Cmd-.?
  341.                     GetDItem(theDialog, cancel, &iType, &iHandle, &iRect);
  342.                     HiliteControl((ControlHandle)iHandle, 1);
  343.                     Delay(8, &endTicks);
  344.                     HiliteControl((ControlHandle)iHandle, 0);
  345.                     *theItem = cancel;
  346.                     return TRUE;
  347.             } 
  348.             else 
  349.             {
  350. #ifdef HAS_ISxxxx    //• The "isxxxxx()" functions are easily implemented with a
  351.                        256-byte lookup table... see "ctype.h"/"ctype.c" in Think C.
  352.                        Then you can trap out illegal keys.  Without them, all keys
  353.                        are valid....
  354.                 switch (gDialogMode) 
  355.                 {
  356.                     case AllowAlpha:
  357.                         result = isalpha(theChar);
  358.                     break;
  359.                     
  360.                     case AllowPrint:
  361.                         result = isprint(theChar);
  362.                     break;
  363.                     
  364.                     case AllowDigit:
  365.                         result = isdigit(theChar);
  366.                     break;
  367.                     
  368.                     case AllowHexDigit:
  369.                         result = isxdigit(theChar);
  370.                     break;
  371.                     
  372.                     case AllowAlphaNum:
  373.                         result = isalnum(theChar);
  374.                     break;
  375.                     
  376.                     default:
  377.                         result = FALSE;
  378.                 }
  379.                 result |= iscntrl(theChar);        //• Always allow spec. keys.
  380. #else
  381.                 result = TRUE;
  382. #endif
  383.                 if (result)
  384.                     return FALSE;
  385.                 else 
  386.                     {
  387.                         SysBeep(1);
  388.                         *theItem = 0;
  389.                         return TRUE;
  390.                 }
  391.             }
  392.             break;
  393.     }
  394.     return result;
  395. }
  396.  
  397. main()
  398. {
  399.     GrafPtr            savePort;
  400.     DialogPtr        theDialog;
  401.     short            itemHit, iType;
  402.     Handle            iHandle, rsrcHandle;
  403.     Boolean            dialogDone = FALSE;
  404.     Rect            iRect;
  405.     Str255            theString;
  406.     long            theValue;
  407.     
  408.     ToolBoxInit();
  409.     
  410.     if ((theDialog = GetNewDialog(130, NIL, (WindowPtr)-1L)) == NIL) {
  411.         SysBeep(1);
  412.         ExitToShell();
  413.     }
  414.     
  415.     GetPort(&savePort);    
  416.     SelectWindow(theDialog);
  417.       SetPort(theDialog);
  418.  
  419.     ShowWindow(theDialog);
  420.     SelIText(theDialog, 4, 0, 32767);
  421.     
  422.     gOkActive = FALSE;
  423.     gDialogMode = AllowDigit;
  424.     while (!dialogDone) 
  425.     {
  426.         //• Get the dialog ok item, the item type, the handle
  427.         //• to the item and its rectangle.  get this stuff.
  428.         GetDItem(theDialog, ok, &iType, &iHandle, &iRect);
  429.         
  430.         //• Hilite that item (not select, but hilite) if it's active.
  431.         HiliteControl((ControlHandle)iHandle, (gOkActive ? 0 : 255));
  432.         
  433.         //• Frame the Okay button. With gray if not active.
  434.         FrameDialogItem(theDialog, ok, (gOkActive ? black : gray));
  435.         
  436.         //• Keep an eye on the dialog and watch for item hits.
  437.         ModalDialog(DialogFilter, &itemHit);
  438.         switch (itemHit) 
  439.         {
  440.             case ok:                //• If the Okay button is hit...
  441.                 dialogDone = TRUE;    //• we are done with the program.
  442.             break;
  443.             
  444.             case cancel:            //• Same here.
  445.                 dialogDone = TRUE;
  446.             break;
  447.             
  448.             case 4:        //• Edit text item.
  449.             case 5:        //• Pict item of small up/down arrows.
  450.                 
  451.                 //• If it's the arrows, get which one - up or down.
  452.                 GetDItem(theDialog, 4, &iType, &iHandle, &iRect);
  453.                 
  454.                 //• In either arrow, we'll get the text, too.
  455.                 GetIText(iHandle, theString);
  456.                 
  457.                 //• Change the text to a numerical value (integer).
  458.                 StringToNum(theString, &theValue);
  459.                 
  460.                 //• If the value is greater than 9...
  461.                 if (theValue > 9)        
  462.                     gOkActive = TRUE;    //• Activate the Okay button.
  463.                 else
  464.                     gOkActive = FALSE;    //• Otherwise, leave it dim.
  465.             break;
  466.         }
  467.     }
  468.     DisposDialog(theDialog);
  469.       SetPort(savePort);
  470. }
  471.